import { customRef } from 'vue'
/**
 * 导出一个函数，用于防抖
 * @param fn 需要防抖的函数
 * @param delay 延迟时间，默认200毫秒
 * @returns
 */
export function useDebounceFn<T extends Function>(fn: T, delay = 200) {
  // 如果延迟时间小于等于0，则直接返回原函数
  if (delay <= 0) {
    return fn
  }
  // 定义一个定时器变量
  let timer: ReturnType<typeof setTimeout> | undefined

  // 定义一个包装函数
  function wrapper(this: any, ...args: any[]) {
    // 定义一个执行函数
    const exec = () => {
      // 清除定时器
      timer = undefined
      // 执行原函数
      return fn.apply(this, args)
    }
    // 如果定时器存在，则清除定时器
    timer && clearTimeout(timer)
    // 设置定时器，延迟执行
    timer = setTimeout(exec, delay)
  }
  // 返回包装函数
  return wrapper as any as T
}

/**
 * 用于创建一个防抖的ref
 * @param value 需要防抖的值
 * @param delay 延迟时间，默认1000毫秒
 * @returns
 */
export function useDebounceRef(value: any, delay = 1000) {
  // 使用customRef创建一个自定义的ref
  return customRef((track, trigger) => {
    // 定义一个定时器
    let timer: ReturnType<typeof setTimeout> | undefined
    return {
      // 当ref被读取时，调用track函数
      get() {
        // 依赖收集
        track()
        // 返回ref的值
        return value
      },
      // 当ref被设置时，调用trigger函数
      set(val) {
        // 如果定时器存在，清除定时器
        timer && clearTimeout(timer)
        // 设置定时器，在delay毫秒后执行
        timer = setTimeout(() => {
          // 更新ref的值
          value = val
          // 触发ref的更新
          trigger()
        }, delay)
      }
    }
  })
}
